package utils

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

//GetCurrentPath ...
func GetCurrentPath() (string, error) {
	file, err := exec.LookPath(os.Args[0])
	if err != nil {
		return "", err
	}
	path, err := filepath.Abs(file)
	if err != nil {
		return "", err
	}
	i := strings.LastIndex(path, "/")
	if i < 0 {
		i = strings.LastIndex(path, "\\")
	}
	return string(path[0 : i+1]), nil
}

//PathExists ...
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

type dirTree struct {
	Label    string    `json:"label"`
	IsLeaf   bool      `json:"isLeaf"`
	Children []dirTree `json:"children"`
	Path     string    `json:"path"`
}

func GetDir(dir string, isdir bool) ([]dirTree, error) {
	// 检查dir是否为空，如果为空或者为"/"，则获取根目录或驱动器列表
	if dir == "" || dir == "/" {
		sysType := runtime.GOOS
		if sysType == "windows" {
			return GetLogicalDrives()
		}
		dir = "/" // 如果操作系统不是windows，设定根目录为"/"
	}

	// 始终保持dir以斜杠结尾
	dir = strings.TrimRight(dir, "/") + "/"
	return listDir(dir, isdir)
}

func GetLogicalDrives() ([]dirTree, error) {
	// 列出所有可能的驱动器
	var drivesAll = []string{"A:", "B:", "C:", "D:", "E:", "F:", "G:", "H:", "I:", "J:", "K:", "L:", "M:", "N:", "O:", "P：", "Q：", "R：", "S：", "T：", "U：", "V：", "W：", "X：", "Y：", "Z："}
	var drives []string

	// 筛选出存在且是目录的驱动器
	for _, v := range drivesAll {
		fi, err := os.Stat(v)
		if err == nil && fi.IsDir() {
			drives = append(drives, v)
		}
	}

	// 创建dirTree列表
	list := make([]dirTree, len(drives))
	for i, k := range drives {
		list[i] = dirTree{
			Path:   k,
			Label:  k,
			IsLeaf: false,
		}
	}
	return list, nil
}

func listDir(dirPth string, isDirOnly bool) ([]dirTree, error) {
	// 读取目录下的所有文件和文件夹
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}

	list := make([]dirTree, 0, len(dir))
	for _, fi := range dir {
		// 如果 isDirOnly 为 true，只列出目录；否则列出所有文件和目录
		if fi.IsDir() || !isDirOnly {
			list = append(list, dirTree{
				Label:  fi.Name(),
				IsLeaf: !fi.IsDir(),
				Path:   filepath.Join(dirPth, fi.Name()),
			})
		}
	}
	return list, nil
}
